#include "util.h"
#include "../math/math.h"
#include "../math/vector.h"

Matrix4f CUtil::readMatrix(FILE* pFP)
{
	float m[12] = {0.0f};
	fread(m, sizeof(float), 12, pFP);

	return Matrix4f(
		m[0],m[1],m[2],0,
		m[3],m[4],m[5],0,
		m[6],m[7],m[8],0,
		m[9],m[10],m[11],1
		);
}

long unsigned int CUtil::getFileSize(FILE* pFP)
{
	long unsigned int p = ftell(pFP);
	fseek(pFP, 0, SEEK_END);
	long unsigned int l = ftell(pFP);
	fseek(pFP, p, 0);
	return l;
}

string CUtil::readString(FILE* pFP)
{
	string value;
	char letter = '\n';
	int itterationCount = 0;
	while(1)
	{
		fread(&letter, sizeof(char), 1, pFP);
		if(itterationCount > MAX_PATH || letter == '\n')
		{
			//char gap;
			//fread(&gap, sizeof(char), 1, pFP);
			break;
		}
		value.concat(letter);
		itterationCount++;
	}
	
	return value;
}

string CUtil::toString(const int value)
{
	char	buffer[10] = {'\0'}; 
	_itoa_s(value,buffer, 10, 10); 
	string str(buffer); 
	return str; 	
}

string CUtil::getFormat(const string& value)
{
	const int dotPos = value.findLastOf('.'); 
	return (-1 == dotPos) ? value : value.substring(dotPos + 1,value.length() - (dotPos + 1)); 
}

string CUtil::getRemoveFilepath(const string& value)
{
	const int slashPos = MAX(value.findLastOf((const char)'\\'), value.findLastOf((const char)'//')) + 1; 
	if(0 == slashPos)
		return value; 
	
	return value.substring(slashPos,value.length() - slashPos); 

}

string CUtil::getFilename(const string& value)
{
	string noFilepath = CUtil::getRemoveFilepath(value); 
	const int slashPos = noFilepath.findLastOf('\\'); 
	if(-1 == slashPos)
	{
		const int dotPos = noFilepath.findLastOf('.'); 
		return (-1 == dotPos) ? noFilepath : noFilepath.substring(0,dotPos - 1); 
	}
	
	const int dotPos = noFilepath.findLastOf('.'); 
	return (-1 == dotPos) ? noFilepath : noFilepath.substring(slashPos,dotPos); 
}

float CUtil::random(float min, float max)
{
	return CUtil::random(fabs(max - min)) + min; 
}

Vector3f CUtil::randomVector(Vector3f axisScale)
{
	return Vector3f(axisScale.x * (float)random(-100.0f,100.0f),axisScale.y * (float)random(-100.0f,100.0f),axisScale.z * (float)random(-100.0f,100.0f));
}

Vector3f CUtil::randomNormalizedVector(Vector3f axisScale)
{
	return Vector3f::normalOf(&randomVector(axisScale));
}

float CUtil::random(float range)
{
	if(range < 0.0f)
		return -random(-range); 

	if(range == 0.0f)
		return 0.0f; 

	const int intRange = (range < 1) ? (int)(1.0f / range) : (int)(10.0f * range); 
	const float random = (float)CUtil::random(intRange); 
	return random * ((range < 1) ? range : 1.0f) * 0.1f; 
}

int CUtil::random(int range)
{
	if(range < 0)
		return -CUtil::random(-range); 

	if(range == 0)
		return 0; 

//	srand(timeGetTime() + 1000);
	return rand() % (range + 1); 
}
bool CUtil::probability(const float p)
{
	const float safeP = CLAMP(p, 1.0f, 0.0f);
	return (CUtil::random(1.0f) < safeP);
}